﻿using Biotech.Log;
using MaterialDesignThemes.Wpf;
using project.B12.application.Ioc;
using project.B12.IService;
using project.B12.Model.Enums;
using project.B12.Model.Models;
using project.B12.ViewModels;
using software.Common.MVVM;
using Software.Common.Util.AppConfig;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Media;

namespace project.B12.application.ViewModels.Dialogs
{
    public class SpecialSampleViewModel:ObservableObject
    {
        private List<int> _columnSamples;
        private List<string> _rowSamples;
        private bool _firstSample = true;
        private bool  _isColumn;
        private int _volumeCount;
        private Table_MonitorMes _monitorMes;
        private IServiceDevice _serviceDevice {  get; set; }
        private IMICPlateMes _mICPlateMes { get; set; }

        public string SampleMethod { get; set; }
        public PublicResourceViewModel PublicResource { get; set; }

        #region Model
        private int lorR;
        public int LorR
        {
            get { return lorR; }
            set
            {
                lorR = value;
                this.RaisePropertyChanged();
            }
        }

        private List<int> columnList { get; set; }
        public List<int> ColumnList
        {
            get { return columnList; }
            set
            {
                columnList = value;
                this.RaisePropertyChanged();
            }
        }

        private List<string> rowList { get; set; }
        public List<string> RowList
        {
            get { return rowList; }
            set
            {
                rowList = value;
                this.RaisePropertyChanged();
            }
        }

        private bool isIncrease;
        public bool IsIncrease
        {
            get { return isIncrease; }
            set
            {
                isIncrease = value;
                this.RaisePropertyChanged();
            }
        }

        private string sampleId;
        public string SampleId
        {
            get { return sampleId; }
            set
            {
                sampleId = value;
                this.RaisePropertyChanged();
            }
        }

        private List<string> projectNames { get; set; }
        public List<string> ProjectNames
        {
            get { return projectNames; }
            set
            {
                projectNames = value;
                this.RaisePropertyChanged();
            }
        }

        private string projectName { get; set; }
        public string ProjectName
        {
            get { return projectName; }
            set
            {
                projectName = value;
                this.RaisePropertyChanged();
            }
        }

        private List<string> sampleTypes { get; set; }
        public List<string> SampleTypes
        {
            get { return sampleTypes; }
            set
            {
                sampleTypes = value;
                this.RaisePropertyChanged();
            }
        }

        private string sampleType { get; set; }
        public string SampleType
        {
            get { return sampleType; }
            set
            {
                sampleType = value;
                this.RaisePropertyChanged();
            }
        }

        private string sampleInput;
        public string SampleInput
        {
            get { return sampleInput; }
            set
            {
                sampleInput = value;
                SampleTypes = PublicResource.BacteriaNames.Where(o => o.Contains(value)).ToList();
                if (string.IsNullOrEmpty(value))
                    SampleType = null;
                this.RaisePropertyChanged();
            }
        }

        private string cultivateTime = "18";
        public string CultivateTime
        {
            get { return cultivateTime; }
            set
            {
                cultivateTime = value;
                this.RaisePropertyChanged();
            }
        }

        private bool isEnabled {  get; set; }
        public bool IsEnabled
        {
            get { return isEnabled; }
            set
            {
                isEnabled = value;
                this.RaisePropertyChanged();
            }
        }

        public class Cell : ObservableObject
        {
            public Cell(int row,int column)
            {
                Row = row;
                Column = column;
                IsEnabled = true;
            }

            public int Row { get;set; }
            public int Column { get;set; }

            private bool _isSelected;
            public bool IsSelected
            {
                get => _isSelected;
                set
                {
                    _isSelected = value;
                    if(IsEnabled)
                        CellColor = value ? new SolidColorBrush(Colors.Red) : new SolidColorBrush(Colors.LightGray); 
                    this.RaisePropertyChanged();
                }
            }

            public bool IsEnabled {  get; set; }

            private System.Windows.Media.Brush cellColor;
            public System.Windows.Media.Brush CellColor
            {
                get { return cellColor; }
                set
                {
                    cellColor = value;
                    this.RaisePropertyChanged();
                }
            }
        }

        private ObservableCollection<Cell> cells { get; set; }
        public ObservableCollection<Cell> Cells
        {
            get { return cells; }
            set
            {
                cells = value;
                this.RaisePropertyChanged();
            }
        }
        #endregion

        public RelayCommand Add => new RelayCommand(AddSample);
        public RelayCommand Finish => new RelayCommand(Complete);
        public RelayCommand Close => new RelayCommand(ExitSpecialSample);
        public RelayCommand<string> ColumnSelectCommand => new RelayCommand<string>((column) =>
        {
            if(_rowSamples.Count > 0|| (!_firstSample&&!_isColumn))
            {
                MessageBox.Show("当前已有选择的行数据");
                return;
            }
            _isColumn = true;
            int index = int.Parse(column);
            var columns=Cells.Where(o=>o.Column == index).ToList();
            if(columns.Any(o=>o.IsSelected==true))
            {
                columns.ForEach(o=>o.IsSelected=false);
                _columnSamples.Remove(index);
            }
            else
            {
                columns.ForEach(o => o.IsSelected = true);
                _columnSamples.Add(index);
            }
            _columnSamples.Sort();
        });

        public RelayCommand<string> RowSelectCommand => new RelayCommand<string>((row) =>
        {
            if (_columnSamples.Count > 0||(!_firstSample &&_isColumn))
            {
                MessageBox.Show("当前已有选择的列数据");
                return;
            }
            _isColumn = false;
            int index = row[0] -'A'+1;
            var rows = Cells.Where(o => o.Row == index).ToList();
            if(rows.Any(o=>o.IsSelected == true))
            {
                rows.ForEach(o=>o.IsSelected=false);
                _rowSamples.Remove(row);
            }
            else
            {
                rows.ForEach(o => o.IsSelected = true);
                _rowSamples.Add(row);
            }
            _rowSamples.Sort();
        });

        public SpecialSampleViewModel(IServiceDevice serviceDevice,IMICPlateMes mICPlateMes) 
        {
            PublicResource=ViewModelLocator.PublicResourceViewModel;
            _serviceDevice=serviceDevice;
            _mICPlateMes = mICPlateMes;
            _monitorMes = new Table_MonitorMes();
            projectNames = new List<string>();
            _columnSamples = new List<int>();
            _rowSamples = new List<string>();
            SampleTypes = new List<string>();
            SampleTypes = PublicResource.BacteriaNames.ToList();
            IsEnabled = true;
            IsIncrease = true;
            _volumeCount = 0;
            ColumnList = new List<int>();
            for(int i=1;i<=12;i++)
            {
                ColumnList.Add(i);
            }
            RowList = new List<string>();
            for(int i=1;i<=8;i++)
            {
                RowList.Add(Convert.ToChar(i+64).ToString());
            }

            Cells = new ObservableCollection<Cell>();
            for (int row = 1; row <=8; row++)
            {
                for (int col = 1; col <=12; col++)
                {
                    Cells.Add(new Cell(row,col) { IsSelected=false});
                }
            }
            
            var monitors = serviceDevice.Items64.Where(o => o.State == HoleState.Free).ToList();
            foreach (var monitor in monitors)
            {
                if(!ProjectNames.Contains(monitor.PlateType.ToString()))
                    ProjectNames.Add(monitor.PlateType.ToString());
            }
        }

        private void AddSample()
        {
            int time = 0;
            if(!CheckCondition(ref time))
            {
                WPF.Controls.Message.Push("未选择加样信息", MessageBoxImage.Warning);
                return;
            }

            List<Cell> currentCells= new List<Cell>();
            if (_columnSamples.Count > 0)
            {
                if (Sample(time, _columnSamples))
                {
                    foreach (var index in _columnSamples)
                    {
                        var columnCells = Cells.Where(o => o.Column == index).ToList();
                        columnCells.ForEach(o => o.IsEnabled = false);
                        columnCells.ForEach(o => o.CellColor = new SolidColorBrush(Colors.Green));
                    }
                    _columnSamples = new List<int>();
                    MessageBox.Show("当前菌液的加样已完成");
                }
            }
            else
            {
                List<int> samples = new List<int>();
                foreach(var item in _rowSamples)
                {
                    samples.Add(item[0] - 'A' + 1);
                }
                if (Sample(time, samples))
                {
                    foreach (var index in samples)
                    {
                        var rowCells = Cells.Where(o => o.Row == index).ToList();
                        rowCells.ForEach(o => o.IsEnabled = false);
                        rowCells.ForEach(o => o.CellColor = new SolidColorBrush(Colors.Green));
                    }
                    _rowSamples = new List<string>();
                    MessageBox.Show("当前菌液的加样已完成");
                }
            }
            _firstSample = false;
            IsEnabled=false;
            
        }

        private bool Sample(int time,List<int> samples)
        {
            List<int> sampleIndex = GetSampleIndexes(samples);
            try
            {
                if (_monitorMes == null)
                    return false;
                if (_firstSample)
                {
                    if (IsIncrease)
                        GetSampleId();
                    _serviceDevice.IsSpecialSample = true;
                    _monitorMes.IsSpecialSample = true;
                    _monitorMes.SampleID = SampleId;
                    _monitorMes.CultureTime = time * 60 * 60;
                    _monitorMes.State = HoleState.WaitingForSample;
                    _monitorMes.LorR = LorR;
                    if (_serviceDevice.IsPhotoInterval)
                    {
                        _monitorMes.PhotoIntervalTime = PublicResource.PhotoTime;
                    }
                    _serviceDevice.SampleSpecialFirst(_monitorMes);
                }
                _monitorMes.IsColumn = _isColumn;
                if (_monitorMes.SpecialSampleTypes.ContainsKey(SampleType))
                {
                    foreach(var item in samples)
                        _monitorMes.SpecialSampleTypes[SampleType].Add(item);
                }
                else
                    _monitorMes.SpecialSampleTypes.Add(SampleType, samples);

                List<int> sampleIndexs = GetSampleIndexes(samples);
                _serviceDevice.SampleSpecial(LorR, sampleIndexs,_volumeCount,_monitorMes);
                return true;
            }
            catch
            {
                return false;
            }
        }

        private List<int> GetSampleIndexes(List<int> samples)
        {
            List<int> sampleIndexes = new List<int>();
            if (_isColumn)
            {
                for (int i = 0; i < samples.Count; i++)
                {
                    if (i % 2 == 0)
                    {
                        for (int j = 0; j < 8; j++)
                        {
                            int index = (samples[i] - 1) * 8 + j;
                            sampleIndexes.Add(index);
                        }
                    }
                    else
                    {
                        for (int j = 7; j >= 0; j--)
                        {
                            int index = (samples[i] - 1) * 8 + j;
                            sampleIndexes.Add(index);
                        }
                    }
                }
            }
            else
            {
                for (int i = 0; i < samples.Count; i++)
                {
                    if (i % 2 == 0)
                    {
                        for (int j = 0; j < 12; j++)
                        {
                            int index = j * 8 + samples[i] - 1;
                            sampleIndexes.Add(index);
                        }
                    }
                    else
                    {
                        for (int j = 11; j >= 0; j--)
                        {
                            int index = j * 8 + samples[i] - 1;
                            sampleIndexes.Add(index);
                        }
                    }
                }
            }
            return sampleIndexes;
        }

        private bool CheckCondition(ref int time)
        {
            if (_rowSamples.Count == 0 && _columnSamples.Count == 0)
                return false;
            if(string.IsNullOrEmpty(ProjectName)||string.IsNullOrEmpty(SampleType))
                return false;
            if (!int.TryParse(cultivateTime, out time))
                return false;
            if (time < 0 || time > 168)
                return false;

            if(_firstSample)
            {
                _monitorMes = _serviceDevice.Items64.Where(o => o.State == HoleState.Free && o.PlateType == ProjectName).First();
                var mf = _mICPlateMes.microplateAntibioticConcentrationMes.Find(p => p.name == _monitorMes.PlateType);
                if (mf == null)
                {
                    throw new Exception("配置文件错误");
                    return false;
                }
                int volume = 0;
                if (int.TryParse(mf.Volume, out volume))
                {
                    _volumeCount = volume / 50;
                }
            }
            return true;
        }

        private void GetSampleId()
        {
            int sampleCount= int.Parse(UtilAppConfig.GetAppConfig("SampleIdCount"));
            if (string.IsNullOrEmpty(SampleId))
            {
                IncreaseSampleId(sampleCount);
                return;
            }
            int length = SampleId.Length;
            if (Regex.IsMatch(SampleId, "[0-9]+$"))
            {
                int number = int.Parse(SampleId.Substring(length - 1)) + 1;
                //SampleId = SampleId.Substring(0, length - 1) + number.ToString();
            }
            else
                IncreaseSampleId(sampleCount);
        }

        private void IncreaseSampleId(int sampleCount)
        {
            SampleId = SampleId + $"{sampleCount:D3}";
            sampleCount++;
            UtilAppConfig.UpdateAppConfig("SampleIdCount", sampleCount.ToString());
        }

        private void Complete()
        {
            _serviceDevice.FinishSampleSpacial(_monitorMes);
            LoggerFactory.Instance.CurrentLogger.LogInfo($"样本编号：{_monitorMes.SampleID}特殊加样已完成", "", "软件");
            if (DialogHost.IsDialogOpen("Main"))
                DialogHost.Close("Main", true);
        }

        private void ExitSpecialSample()
        {
            if(_serviceDevice.deviceState!=DeviceState.运行)
            {
                if (DialogHost.IsDialogOpen("Main"))
                    DialogHost.Close("Main", true);
                return;
            }

            MessageBoxResult result = MessageBox.Show("当前正在加样，请确认是否取消加样？", "", MessageBoxButton.OKCancel, MessageBoxImage.Question);
            if (result == MessageBoxResult.Cancel)
                return;

            if (_monitorMes.State == HoleState.SAMPLING)
            {
                _serviceDevice.DiscontinueDevice();

                LoggerFactory.Instance.CurrentLogger.LogInfo(_monitorMes.PlateID + "取消左加样", "", "软件");
            }
            if (DialogHost.IsDialogOpen("Main"))
                DialogHost.Close("Main", true);
        }
    }
}
